package com.hllxd.hism.star.basic.service.config.mysql.datasource;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Configuration
public class DruidDataSourceConfiguration {

    @Autowired
    private DataSourcePropertiesDoris dorisDataSourceProperties;

    @Autowired
    private DataSourcePropertiesDoris3 dorisDataSourceProperties3;

    @Autowired
    private DataSourcePropertiesMis misDataSourceProperties;

    @Bean
    public ServletRegistrationBean DruidStatViewServlet(){

        ServletRegistrationBean
            servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        //登录查看信息的账号密码.
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        servletRegistrationBean.addInitParameter("loginPassword","admin");
        //是否能够重置数据.
        servletRegistrationBean.addInitParameter("resetEnable","false");

        servletRegistrationBean.setServlet(new StatViewServlet());
        servletRegistrationBean.setEnabled(false);
        return servletRegistrationBean;
    }
    @Bean
    public FilterRegistrationBean druidStatFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid2/*");
        return filterRegistrationBean;
    }
    @Primary
    @Bean(initMethod = "init", destroyMethod = "close",name = "dorisDataSource")
    public DataSource druidDataSource1() {
        return getDataSource(dorisDataSourceProperties);
    }

    @Bean(initMethod = "init", destroyMethod = "close",name = "dorisDataSource3")
    public DataSource druidDataSource3() {
        return getDataSource(dorisDataSourceProperties3);
    }

    @Bean(initMethod = "init", destroyMethod = "close",name = "misDataSource")
    public DataSource druidDataSource2() {
        return getDataSource(misDataSourceProperties);
    }


    private DataSource getDataSource(DataSourceProperties properties) {
        log.info("initial-size: {}, max-active: {}, min-idle: {}.", properties.getInitialSize(), properties.getMaxActive(),
            properties.getMinIdle());
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(properties.getDriverClassName());
        druidDataSource.setUrl(properties.getUrl());
        druidDataSource.setUsername(properties.getUsername());
        druidDataSource.setPassword(properties.getPassword());
        druidDataSource.setInitialSize(properties.getInitialSize());
        druidDataSource.setMinIdle(properties.getMinIdle());
        druidDataSource.setMaxActive(properties.getMaxActive());
        druidDataSource.setKeepAlive(true);
//        druidDataSource.setProxyFilters(setProxyFilters());
        druidDataSource.setTestWhileIdle(true);// 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.

        druidDataSource.setTimeBetweenEvictionRunsMillis(60000);// 60s
        druidDataSource.setMinEvictableIdleTimeMillis(300000);// 300s
        druidDataSource.setValidationQuery(properties.getValidationQuery());
        druidDataSource.setTestOnBorrow(true);// 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
        druidDataSource.setTestOnReturn(false);// 指明是否在归还到池中前进行检验
        druidDataSource.setRemoveAbandonedTimeoutMillis(60000); // 是否自动回收超时连接
        druidDataSource.setMaxWait(60000);//60s 最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数),超过时间则抛出异常,如果设置为-1表示无限等待
        druidDataSource.setPoolPreparedStatements(true);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(properties.getInitialSize());

        try {
            log.info("Setting 'application.yml' into druid");
            druidDataSource.setFilters("stat");
        } catch (SQLException e) {
            throw new IllegalStateException("Could not initial Druid DataSource\n" + e);
        }
        return druidDataSource;
    }

    public WallConfig druidWallConfig(){
        WallConfig wallConfig = new WallConfig();
        wallConfig.setMultiStatementAllow(true);
        return wallConfig;
    }

    private List<Filter> setProxyFilters(){
        List<Filter> filters = new ArrayList<Filter>();
        WallConfig wallConfig = druidWallConfig();
        WallFilter filter = new WallFilter();
        filter.setConfig(wallConfig);
        filters.add(filter);
        return  filters;
    }
}
